# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: data_analysis_view.py
  @time: 2022/6/29 15:26
  @desc:
"""
from PyQt5 import QtWidgets
from PyQt5 import sip
from PyQt5.QtCore import QSize, pyqtSignal, QPoint, QTimer, QDate, QThread
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QTextLine
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QPushButton, QVBoxLayout, QTableView, QFrame, QAbstractItemView, \
    QMessageBox, QTableWidgetItem, QFileDialog
from gui.custom_widget.my_matrix import Matrix
import numpy as np
from gui.driver.var_manager import VarManager
import csv
from utils.log_util import loggings
from my_thread.vpi_stability_task import VpiStabilityTask
from my_thread.stability_task import VerifyStabilityTask
from my_thread.repeatability_task import RepeatabilityTask
from my_thread.idark_repeatability_task import IdarkRepeatabilityTask
from gui.stability_repeatability_test.stabilityDialog import StabilityDialog
from gui.stability_repeatability_test.vpiStabilityDialog import VpiStabilityDialog
from gui.stability_repeatability_test.VpiCommonDialog import VpiCommonDialog
from gui.stability_repeatability_test.repeatabilityDialog import RepeatabilityDialog
from gui.stability_repeatability_test.iDark_repeatabilityDialog import IDarkRepeatabilityDialog
from gui.custom_widget.infoDialog import auto_close_dialog

widget_header_color = "QHeaderView::section{background:gray;}"


class StabilityRepeatabilityView(QWidget):
    def __init__(self):
        super().__init__()
        with open("./static/style_sheet/origin.qss", mode='r', encoding='utf-8') as f:
            style_sheet = f.read()
        self.setStyleSheet(style_sheet)
        self.var_manage = VarManager()
        self.stability_thread = None
        self.stability_dialog = None
        self.repeatability_dialog = None
        self.stability_task = None
        self.repeatability_task = None
        self.vpi_stability_dialog = None
        self.dcp_list = None
        self.idark_repeatability_dialog = None
        self.idark_repeatability_task = None
        self.initUI()
        self.thread_pool = []
        self.bind_event()

    def set_dcp_list(self, dcp_list):
        if dcp_list:
            self.dcp_list = dcp_list

    def bind_event(self):
        self.btn_stability.clicked.connect(self.show_stability_dialog)
        self.btn_repeatability.clicked.connect(self.show_repeatability_dialog)
        self.btn_idark_repeatability.clicked.connect(self.show_idark_repeatability_dialog)
        self.btn_vpi_stability.clicked.connect(self.show_vpi_stability_dialog)
        self.btn_save_data.clicked.connect(self.show_save_data_dialog)

    def show_vpi_stability_dialog(self):
        if self.dcp_list:
            if self.vpi_stability_dialog is None:
                self.vpi_stability_dialog = VpiCommonDialog(self.dcp_list)
                self.vpi_stability_dialog.send_setting_info.connect(self.start_vpi_test)
            self.vpi_stability_dialog.exec_()
        else:
            print("self.vpi_stability_dialog", self.vpi_stability_dialog)

    def start_vpi_test(self, para_list):
        print("para_list", para_list)
        self.vpi_stability_task = VpiStabilityTask(para_list)
        self.vpi_stability_thread = QThread()
        self.vpi_stability_task.moveToThread(self.vpi_stability_thread)
        self.vpi_stability_thread.started.connect(self.vpi_stability_task.run)
        # self.vpi_stability_task.result_signal.connect(self.show_dark_current_result)
        # self.vpi_stability_task.finished_signal.connect(self.show_finished_view)
        self.vpi_stability_task.finished_signal.connect(self.vpi_stability_thread.quit)
        self.vpi_stability_task.finished_signal.connect(self.vpi_stability_task.deleteLater)
        self.vpi_stability_thread.finished.connect(self.vpi_stability_thread.deleteLater)
        self.vpi_stability_thread.finished.connect(self.vpi_stability_thread.wait)
        self.vpi_stability_thread.start()
        self.thread_pool.append(self.vpi_stability_thread)

    def show_save_data_dialog(self):
        file_path, ok = QFileDialog.getSaveFileName(self, "数据文件存储位置", "./",
                                                    "Data Files (*.csv)")
        try:
            data_row = self.tw_data.rowCount()
            data_column = self.tw_data.columnCount()
            text_list = []
            for row in range(data_row):
                text_row = []
                for column in range(data_column):
                    cell_text = self.tw_data.item(row, column).text()
                    if cell_text:
                        text_row.append(cell_text)
                if text_row:
                    text_list.append(text_row)
            if file_path:
                with open(file_path, "w", newline="") as fw:
                    csv_obj = csv.writer(fw)
                    for row in text_list:
                        csv_obj.writerow(row)
        except Exception as e:
            loggings.error("show_save_data_dialog" + str(e))

    def show_idark_repeatability_dialog(self):
        if self.idark_repeatability_dialog is None:
            self.idark_repeatability_dialog = IDarkRepeatabilityDialog()
            self.idark_repeatability_dialog.dialogSignal.connect(self.start_idark_repeatability_test)
        self.idark_repeatability_dialog.exec_()

    def start_idark_repeatability_test(self, duration, fren):
        self.clear_graph()
        self.idark_repeatability_task = IdarkRepeatabilityTask(duration, fren)
        self.idark_repeatability_thread = QThread()
        self.idark_repeatability_task.moveToThread(self.idark_repeatability_thread)
        self.idark_repeatability_thread.started.connect(self.idark_repeatability_task.run)
        self.idark_repeatability_task.result_signal.connect(self.show_dark_current_result)
        self.idark_repeatability_task.finished_signal.connect(self.show_finished_view)
        self.idark_repeatability_task.finished_signal.connect(self.idark_repeatability_thread.quit)
        self.idark_repeatability_task.finished_signal.connect(self.idark_repeatability_task.deleteLater)
        self.idark_repeatability_thread.finished.connect(self.idark_repeatability_thread.deleteLater)
        self.idark_repeatability_thread.finished.connect(self.idark_repeatability_thread.wait)
        self.idark_repeatability_thread.start()
        self.matrix.setSupTitle("PD Dark Current曲线")
        self.matrix.setX_label("Voltage(V)")
        self.matrix.setY_label("Current(A)")
        header_label = ["Voltage(V)", "Current(A)"]
        self.tw_data.setHorizontalHeaderLabels(header_label)
        self.tw_data.clearContents()
        self.tw_data.setRowCount(0)
        self.thread_pool.append(self.idark_repeatability_thread)

    def show_dark_current_result(self, voltage_list, current_list):
        self.matrix.plot_curve(voltage_list, current_list, is_invert_y=False, is_log=True)
        self.refresh_table_data([voltage_list, current_list])

    def show_repeatability_dialog(self):
        if self.repeatability_dialog is None:
            self.repeatability_dialog = RepeatabilityDialog()
            self.repeatability_dialog.dialogSignal.connect(self.start_repeatability_test)
        self.repeatability_dialog.exec_()

    def start_repeatability_test(self, duration, fren):
        self.clear_graph()
        self.repeatability_task = RepeatabilityTask(duration, fren)
        self.repeatability_thread = QThread()
        self.repeatability_task.moveToThread(self.repeatability_thread)
        self.repeatability_thread.started.connect(self.repeatability_task.run)
        self.repeatability_task.result_signal.connect(self.show_lossgc_result)
        self.repeatability_task.error_signal.connect(self.show_error_info)
        self.repeatability_task.finished_signal.connect(self.show_finished_view)
        self.repeatability_task.finished_signal.connect(self.repeatability_thread.quit)
        self.repeatability_task.finished_signal.connect(self.repeatability_task.deleteLater)
        self.repeatability_thread.finished.connect(self.repeatability_thread.deleteLater)
        self.repeatability_thread.finished.connect(self.repeatability_thread.wait)
        self.repeatability_thread.start()
        self.matrix.setSupTitle("refrence_loss_gc曲线")
        self.matrix.setX_label("WaveLength(nm)")
        self.matrix.setY_label("Power(dBm)")
        header_label = ["WaveLength(nm)", "Power(dBm)"]
        self.tw_data.setHorizontalHeaderLabels(header_label)
        self.tw_data.clearContents()
        self.tw_data.setRowCount(0)
        self.thread_pool.append(self.repeatability_thread)

    def show_stability_dialog(self):
        if self.stability_dialog is None:
            self.stability_dialog = StabilityDialog()
            self.stability_dialog.dialogSignal.connect(self.start_stability_test)
        self.stability_dialog.exec_()

    def start_stability_test(self, duration, interval):
        self.clear_graph()
        self.x_data = []
        self.y_data = []
        self.stability_task = VerifyStabilityTask(duration, interval)
        self.stability_thread = QThread()
        self.stability_task.moveToThread(self.stability_thread)
        self.stability_thread.started.connect(self.stability_task.run)
        self.stability_task.result_signal.connect(self.show_result)
        self.stability_task.error_signal.connect(self.show_error_info)
        self.stability_task.finished_signal.connect(self.show_finished_view)
        self.stability_task.finished_signal.connect(self.stability_thread.quit)
        self.stability_task.finished_signal.connect(self.stability_task.deleteLater)
        self.stability_thread.finished.connect(self.stability_thread.deleteLater)
        self.stability_thread.finished.connect(self.stability_thread.wait)
        self.stability_thread.start()
        self.matrix.setSupTitle("时间和功率关系曲线")
        self.matrix.setX_label("Time(s)")
        self.matrix.setY_label("Power(dBm)")
        header_label = ["Time(s)", "Power(dBm)"]
        self.tw_data.setHorizontalHeaderLabels(header_label)
        self.tw_data.clearContents()
        self.tw_data.setRowCount(0)
        self.thread_pool.append(self.stability_thread)

    def show_error_info(self, error_msg):
        auto_close_dialog(self,error_msg)

    def show_finished_view(self):
        auto_close_dialog(self,"测试完成！")

    def show_lossgc_result(self, x_data, y_data):
        self.matrix.plot_curve(x_data, y_data, is_invert_y=True)
        self.refresh_table_data([x_data, y_data])

    def show_result(self, x_value, y_value):
        if x_value != "" and y_value != "":
            self.clear_graph()
            self.x_data.append(x_value)
            self.y_data.append(y_value)
            self.matrix.setX_label("Time(s)")
            self.matrix.setY_label("Power(dBm)")
            self.matrix.plot_spot_curve(self.x_data, self.y_data)
            self.refresh_spot_table_data([[x_value], [y_value]])

    def refresh_spot_table_data(self, test_data):
        try:
            original_row = self.tw_data.rowCount()
            total_row = len(test_data[0]) + original_row
            self.tw_data.setRowCount(total_row)
            new_data = np.transpose(np.array(test_data))
            for col in range(len(new_data[0])):
                self.tw_data.setItem(original_row, col, QTableWidgetItem(str(new_data[0][col])))
        except Exception as e:
            loggings.error("refresh_spot_table_data" + str(e))

    def refresh_table_data(self, test_data):
        try:
            original_row = self.tw_data.rowCount()
            total_row = len(test_data[0]) + original_row
            self.tw_data.setRowCount(total_row)
            new_data = np.transpose(np.array(test_data))
            for row in range(original_row, total_row):
                for col in range(len(new_data[0])):
                    self.tw_data.setItem(row, col, QTableWidgetItem(str(new_data[row - original_row][col])))
        except Exception as e:
            loggings.error("refresh_table_data" + str(e))

    def closeEvent(self, event):
        if self.stability_task:
            self.stability_task.flag = False
        if self.repeatability_task:
            self.repeatability_task.flag = False
        if self.idark_repeatability_task:
            self.idark_repeatability_task.flag = False

        for thread in self.thread_pool:
            if thread.isRunning():
                thread.quit()
                if thread.isFinished():
                    del thread

    def clear_graph(self):
        self.matrix.clear()
        self.matrix.show_spines()
        self.matrix.show_grid()

    def save_graph(self, image_path):
        self.matrix.saveImage(image_path)


    def initUI(self):
        self.setWindowTitle("稳定性重复性测试页面")
        self.showMaximized()
        self.mainhboxLayout = QHBoxLayout(self)
        self.frame = QFrame(self)
        self.mainhboxLayout.addWidget(self.frame)
        self.hl_total = QHBoxLayout(self.frame)

        self.gb_btn = QtWidgets.QGroupBox("测试模式")
        self.gb_btn.setObjectName("gb_btn")

        self.vl_btn = QVBoxLayout(self.gb_btn)
        self.hboxLayout = QHBoxLayout()

        self.btn_stability = QPushButton(self.frame)
        self.btn_stability.setText("LossGC稳定性测试")

        self.btn_repeatability = QPushButton(self.frame)
        self.btn_repeatability.setText("LossGC重复性测试")

        self.btn_idark_repeatability = QPushButton(self.frame)
        self.btn_idark_repeatability.setText("暗电流稳定性测试")

        self.btn_vpi_stability = QPushButton(self.frame)
        self.btn_vpi_stability.setText("Vpi稳定性测试")

        self.btn_save_data = QPushButton(self.frame)
        self.btn_save_data.setText("保存测试数据")

        self.matrix = Matrix(self.frame)
        self.matrix.setFixedHeight(600)
        self.tw_data = QtWidgets.QTableWidget(self.frame)
        self.tw_data.horizontalHeader().setStyleSheet(widget_header_color)
        self.tw_data.setObjectName("tw_data")
        self.tw_data.setColumnCount(2)
        self.tw_data.setShowGrid(True)
        self.tw_data.setMouseTracking(True)
        self.tw_data.setRowCount(0)
        self.tw_data.scrollToBottom()
        self.tw_data.setFrameShape(QtWidgets.QFrame.NoFrame)

        self.vl_data_page = QVBoxLayout()
        self.vl_data_page.addWidget(self.matrix)
        self.vl_data_page.addWidget(self.tw_data)
        self.hboxLayout.addLayout(self.vl_data_page)

        self.vl_btn.addWidget(self.btn_stability)
        self.vl_btn.addWidget(self.btn_idark_repeatability)
        self.vl_btn.addWidget(self.btn_repeatability)
        self.vl_btn.addWidget(self.btn_vpi_stability)
        self.vl_btn.addWidget(self.btn_save_data)

        self.vl_btn.addStretch(1)

        self.hl_total.addWidget(self.gb_btn)
        self.hl_total.addLayout(self.hboxLayout)
        self.setLayout(self.mainhboxLayout)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    myWindow = StabilityRepeatabilityView()
    myWindow.show()
    sys.exit(app.exec_())
